package com.cqie.service.impl;

import com.cqie.dto.MessageDto;
import com.cqie.dto.MessageListDto;
import com.cqie.dto.TokenUserLoginDto;
import com.cqie.entity.ChatMessage;
import com.cqie.exception.SpecialException;
import com.cqie.mapper.ChatMessageMapper;
import com.cqie.service.IChatMessageService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqie.service.IDoctorInfoService;
import com.cqie.service.IPatientInfoService;
import com.cqie.threadlocal.UserThreadLocal;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 不吃海鲜
 * @since 2024-12-24
 */
@Service
public class ChatMessageServiceImpl extends ServiceImpl<ChatMessageMapper, ChatMessage> implements IChatMessageService {

    @Resource
    private ChatMessageMapper chatMessageMapper;

    private final IPatientInfoService patientInfoService;

    private final IDoctorInfoService doctorInfoService;

    public ChatMessageServiceImpl(IPatientInfoService patientInfoService, IDoctorInfoService doctorInfoService) {
        this.patientInfoService = patientInfoService;
        this.doctorInfoService = doctorInfoService;
    }

    /**
     * 发送消息
     *
     * @param messageDto
     * @return
     * @throws SpecialException
     */
    @Override
    public Boolean sendMessage(MessageDto messageDto) throws SpecialException {
        // 获取发送者消息
        TokenUserLoginDto tokenDto = UserThreadLocal.get(TokenUserLoginDto.class);

        Integer serderId = null;
        String serderName = null;
        String receiverName = null;

        // 如果医生不为空但患者为空，发送者是医生
        if (ObjectUtils.isEmpty(tokenDto.getDoctorId()) && !ObjectUtils.isEmpty(tokenDto.getPatientId())) {
            serderId = tokenDto.getPatientId();
            serderName = patientInfoService.getPatientInfoById(serderId).getPatientName();
            receiverName = doctorInfoService.getDoctorInfoById(messageDto.getReceiverId()).getDoctorName();
        // 如果医生为空但患者不为空，发送者是患者
        } else if (ObjectUtils.isEmpty(tokenDto.getPatientId()) && !ObjectUtils.isEmpty(tokenDto.getDoctorId())) {
            serderId = tokenDto.getDoctorId();
            serderName = doctorInfoService.getDoctorInfoById(serderId).getDoctorName();
            receiverName = patientInfoService.getPatientInfoById(messageDto.getReceiverId()).getPatientName();
        }
        messageDto.setSerderId(serderId);
        messageDto.setSerderName(serderName);
        messageDto.setReceiverName(receiverName);

        if (ObjectUtils.isEmpty(messageDto.getSerderId())) {
            throw new SpecialException("发送者不能为空");
        }

        if (ObjectUtils.isEmpty(messageDto.getReceiverId())) {
            throw new SpecialException("接受者不能为空");
        }

        if (ObjectUtils.isEmpty(messageDto.getSessionId())) {
            throw new SpecialException("会议id不能为空");
        }

        if (ObjectUtils.isEmpty(messageDto.getContent())) {
            throw new SpecialException("消息内容不能为空");
        }


        return chatMessageMapper.sendMessage(messageDto);
    }

    /**
     * 根据会话ID获取消息
     *
     * @param sessionId
     * @return
     */
    @Override
    public List<MessageListDto> getMessagesBySessionId(Integer sessionId) {
        // 会话id不能为空
        if (ObjectUtils.isEmpty(sessionId)) {
            return new ArrayList<>();
        }

        var messageList = chatMessageMapper.getMessagesBySessionId(sessionId);

        // 接收者是患者
        // 根据患者id获取患者信息
        var patient = patientInfoService.getPatientInfoById(messageList.get(0).getReceiverId());

        // 发送者是医生
        // 根据医生id获取医生信息
        var doctor = doctorInfoService.getDoctorInfoById(messageList.get(0).getSerderId());

        for (var message : messageList) {
            message.setReceiverName(patient.getPatientName());
            message.setReceiverAge(calculateAge(patient.getPatientIdCard()));
            message.setReceiverSex(patient.getPatientSexName());
            message.setSerderdepartmentCode(doctor.getDepartmentCode());
            message.setSerderdepartmentName(doctor.getDepartmentName());
        }


        return messageList;
    }

    /**
     * 根据身份证号码计算年龄
     *
     * @param idCard 身份证号码
     * @return 年龄
     */
    public static String calculateAge(String idCard) {
        if (idCard == null || idCard.length() != 18) {
            throw new IllegalArgumentException("身份证号码无效");
        }

        // 提取出生年月日
        String birthYear = idCard.substring(6, 10);
        String birthMonth = idCard.substring(10, 12);
        String birthDay = idCard.substring(12, 14);

        // 将出生日期转换为LocalDate对象
        LocalDate birthDate = LocalDate.parse(birthYear + birthMonth + birthDay, DateTimeFormatter.ofPattern(
                "yyyyMMdd"));
        LocalDate currentDate = LocalDate.now();

        // 计算年龄
        return String.valueOf(Period.between(birthDate, currentDate).getYears());
    }

//    public static void main(String[] args) {
//        String idCard = "12345619900101001X"; // 示例身份证号码
//        int age = calculateAge(idCard);
//        System.out.println("根据身份证号码计算的年龄是: " + age);
//    }
//

    /**
     * 获取会话消息列表
     *
     * @return
     */
    @Override
    public List<MessageListDto> getSessionList(String likeQuery) {
        var sessionList = chatMessageMapper.getSessionList(likeQuery);

        // 使用LinkedHashMap来保持插入顺序，以便最后插入的是每个sessionId的最新消息
        Map<Integer, MessageListDto> latestMessagesBySessionId = new HashMap<>();

        for (MessageListDto message : sessionList) {
            // 如果当前消息的sessionId还没有对应的消息，或者当前消息比已有的消息更新，则更新它
            if (!latestMessagesBySessionId.containsKey(message.getSessionId()) ||
                    message.getUpdateTime().isAfter(latestMessagesBySessionId.get(message.getSessionId()).getUpdateTime())) {
                latestMessagesBySessionId.put(message.getSessionId(), message);
            }
        }

        // 返回包含每个sessionId最后一条消息的列表
        return new ArrayList<>(latestMessagesBySessionId.values());
    }

    /**
     * 创建会议
     * @param messageListDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createSession(MessageListDto messageListDto) throws SpecialException {
        // 获取发送者消息
        TokenUserLoginDto patientDto = UserThreadLocal.get(TokenUserLoginDto.class);
        var patientName = patientInfoService.getPatientInfoById(patientDto.getPatientId()).getPatientName();

        // 设置接收者信息
        var sessionId = createSessionId();
        messageListDto.setReceiverId(patientDto.getPatientId());
        messageListDto.setReceiverName(patientName);
        messageListDto.setSessionId(sessionId);
        chatMessageMapper.createSession(messageListDto);
        return sessionId;
    }

    /**
     * 根据会话ID获取消息
     * @param sessionId
     * @return
     */
    @Override
    public List<MessageListDto> getBySessionId(Integer sessionId) throws SpecialException {
        if(ObjectUtils.isEmpty(sessionId)){
            throw new SpecialException("会话ID不能为空");
        }
        return chatMessageMapper.getBySessionId(sessionId);
    }


    /**
     *  生成1-9的随机数字
     * @return
     */
    private Integer createSessionId() throws SpecialException {
        Random random = new Random();
        StringBuilder sessionIdBuilder = new StringBuilder();
        // 生成8位随机数字
        for (int i = 0; i < 8; i++) {
            int number = random.nextInt(9) + 1; // 生成1到9之间的随机数
            sessionIdBuilder.append(number);
        }
        Integer sessionId = Integer.valueOf(sessionIdBuilder.toString());

        var result = chatMessageMapper.getSessionId(sessionId) > 0;

        if (result){
            throw new SpecialException("创建失败，请重新创建");
        }

        return Integer.valueOf(sessionIdBuilder.toString());
    }


}
